package com.wxtl.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 对象工具
 * 把对象写到流里的过程是串行化（Serilization）过程，但是在Java程序师圈子里又非常形象地称为“冷冻ဦ瀢腌咸菜（picking）ဨ¿程ﺿ
 * 而把对象从流中读出来的并行化（Deserialization）过程则叫做“解冻ဦ瀢回鰿depicking)”过程‥º当指出的是，写在流里的是对象的䶿¸ª拷贝ﺿ
 * 而原对象仍然存在于JVM里面，因此ဨ成咸菜”的只是对象的一个拷贝，Java咸菜还可以回鲜Ὅ
 * 在Java语言里深复制䶿¸ª对象，常常可以先使对象实现Serializable接口，然后把对象（实际上只是对象的一个拷贝）写到䶿¸ª流里（腌成咸菜）ﺿ
 * 再从流里读出来（把咸菜回鲜），便可以重建对象⾿
 * 
 * @author hc24
 * 
 */
public class Objecter{

    private Objecter(){}

    /**
     * 将对象序列化并压缩编码为字符䶿
     * 
     * @param o 对象
     * @return 字符䶿
     * @throws IOException
     */
    public synchronized static String encode(Object o) throws IOException{
        ByteArrayOutputStream bObject = null;
        ByteArrayOutputStream bZip = null;
        ObjectOutputStream outObject = null;
        ZipOutputStream outZip = null;
        try{
        	bObject = new ByteArrayOutputStream();
        	bZip = new ByteArrayOutputStream();
        	outObject = new ObjectOutputStream(bObject);
        	outObject.writeObject(o);
        	outObject.flush();
        	outZip = new ZipOutputStream(bZip);
        	outZip.putNextEntry(new ZipEntry("0"));
        	outZip.write(bObject.toByteArray());
        	outZip.closeEntry();
            return new BASE64Encoder().encode(bZip.toByteArray());
        }finally{
        	try{
        		outZip.close();
        		bZip.close();
        		outObject.close();
        		bObject.close();
        	}catch(Exception e){}
        	outZip = null;
        	bZip = null;
        	outObject = null;
        	bObject = null;
        }
    }

    /**
     * 将字符串解压缩并解码转换为对诿
     * 
     * @param s 字符䶿
     * @return 对象
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public synchronized static Object decode(String s) throws IOException, ClassNotFoundException{
        ByteArrayOutputStream bObject = null;
        ByteArrayInputStream bZip = null;
        ObjectInputStream inObject = null;
        ZipInputStream inZip = null;
        try{
        	bObject = new ByteArrayOutputStream();
        	bZip = new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(s));
        	inZip = new ZipInputStream(bZip);
        	inZip.getNextEntry();
        	byte[] buffer = new byte[1024]; 
        	int offset = -1;
        	while((offset = inZip.read(buffer)) != -1) { 
        		bObject.write(buffer, 0, offset);
        	}
        	inObject = new ObjectInputStream(new ByteArrayInputStream(bObject.toByteArray()));
            return inObject.readObject();
        }finally{
        	try{
        		inZip.close();
        		bZip.close();
        		inObject.close();
        		bObject.close();
        	}catch(Exception e){}
        	inZip = null;
        	bZip = null;
        	inObject = null;
        	bObject = null;
        }
    }
    
    /**
     * 把Map转化成指定对象，把Map中存在的属倧䀨µ给T，如果不存在，则不做操作
     * @param map
     * @param clazz
     * @return
     */
    public static <T> void tranMapToObj(Map<String, Object> map,T t){
    	/* 通过解析T对象得到表名、所有表字段和㽠*/
		Class<T> cls=(Class<T>) t.getClass();
		Method[] methods= cls.getMethods();
		
		for(Method m:methods){
			if(m.getName().startsWith("set")
					&&m.getDeclaringClass().equals(cls)
					&&m.getGenericParameterTypes().length==1){
				String methodName=m.getName();
				String keyName=methodName.substring(3, 4).toLowerCase()+methodName.substring(4);
				Object value=map.get(keyName);
				try {
					if(value!=null)
						m.invoke(t, map.get(keyName));
				} catch (Exception e) {}					
			}
		}
    }
    
}